package com.zego.wawaji.base.invoker;

import android.app.Activity;
import android.content.ClipData;
import android.content.Context;
import android.os.Build;
import android.support.v4.app.FragmentActivity;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.zego.wawaji.R;
import com.zego.wawaji.base.log.PLogger;
import com.zego.wawaji.base.log.PToast;
import com.zego.wawaji.base.module.ModuleMgr;
import com.zego.wawaji.base.observer.MsgMgr;
import com.zego.wawaji.base.utils.APKUtil;
import com.zego.wawaji.base.utils.ChineseFilter;
import com.zego.wawaji.base.utils.JsonUtil;
import com.zego.wawaji.http.request.HttpResponse;
import com.zego.wawaji.http.request.RequestComplete;
import com.zego.wawaji.third.share.ShareUtils;
import com.zego.wawaji.ui.dialog.PickerDialogUtil;
import com.zego.wawaji.ui.dialog.SimpleTipDialog;
import com.zego.wawaji.wawaji_client.App;

import org.json.JSONObject;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;


/**
 * CMD操作统一处理
 */
public class Invoker {

    private WebAppInterface appInterface = new WebAppInterface(App.getContext(), null);
    private Object webView;

    /**
     * @return 获取持有的WebAppInterface实例
     */
    public WebAppInterface getWebAppInterface() {
        return appInterface;
    }

    //--------------------CMD处理start--------------------

    private static class SingletonHolder {
        public static Invoker instance = new Invoker();
    }

    public static Invoker getInstance() {
        return SingletonHolder.instance;
    }

    private Invoke invoke = new Invoke();

    /**
     * 根据command和data执行对应方法（处理在app内情况）
     *
     * @param appInterface WebAppInterface实例
     * @param cmd          CMD操作码
     * @param data         操作执行的json字符串数据
     */
    public void doInApp(WebAppInterface appInterface, final String cmd, final String data) {
        this.appInterface = (appInterface == null ? new WebAppInterface(App.getContext(), null) : appInterface);
        webView = appInterface == null ? null : appInterface.getWebView();

        MsgMgr.getInstance().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    Method notifyCMDMethod = Invoke.class.getMethod(cmd, String.class);
                    notifyCMDMethod.invoke(invoke, data);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 本地调用执行JS逻辑
     *
     * @param cmd  JS cmd命令
     * @param data 传递给JS的数据
     */
    public void doInJS(String cmd, Map<String, Object> data) {
        Map<String, Object> cmdMap = new HashMap<>();
        cmdMap.put("jcmd", cmd);
        cmdMap.put("data", data == null ? new HashMap<>() : data);
        String url = "javascript:appCommand('" + JSON.toJSONString(cmdMap) + "')";
        doInJS(url);
    }

    /**
     * 本地调用执行JS逻辑：特殊情况主动调用，如base64图片传输，无需转码
     *
     * @param callbackName   回调方法名
     * @param callbackID     回调id
     * @param responseString 调用传值
     * @param isTranscode    是否进行字符串转码
     */
    public void doInJS(final String callbackName, final String callbackID, final String responseString, final boolean isTranscode) {
        Flowable.create(new FlowableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull FlowableEmitter<String> e) throws Exception {
                e.onNext(isTranscode ? ChineseFilter.toUnicode(responseString) : responseString);
                e.onComplete();
            }
        }, BackpressureStrategy.BUFFER).subscribeOn(Schedulers.io()).
                observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {
            @Override
            public void accept(@NonNull String s) throws Exception {
                doInJS("javascript:" + callbackName + "(\'" + callbackID + "\',\'" + s + "\')");
            }
        });
    }

    /**
     * 本地调用执行JS逻辑，默认进行字符串转码，以支持中文字符串的传输
     *
     * @param callbackName   回调方法名
     * @param callbackID     回调id
     * @param responseString 是否进行字符串转码
     */
    public void doInJS(String callbackName, String callbackID, String responseString) {
        doInJS(callbackName, callbackID, responseString, true);
    }

    /**
     * 本地调用执行JS逻辑
     *
     * @param loadUrl 调用执行的命令
     */
    public void doInJS(String loadUrl) {
        if (webView != null) {
            if (webView instanceof com.tencent.smtt.sdk.WebView) {
                ((com.tencent.smtt.sdk.WebView) webView).loadUrl(loadUrl);
                PLogger.d("---tencent x5--->" + loadUrl);
            } else if (webView instanceof android.webkit.WebView) {
                ((android.webkit.WebView) webView).loadUrl(loadUrl);
                PLogger.d("---webkit--->" + loadUrl);
            }
        }
    }

    /**
     * 设置webView，每次webView页面可见的时候重设
     *
     * @param webView WebView实例
     */
    public void setWebView(Object webView) {
        this.webView = webView;
        PLogger.d("------>" + String.valueOf(webView));
    }

    //--------------------CMD处理end--------------------

    public class Invoke {
        // 结束当前游戏页面
        public void do_finish(String data) {
            // [注意]：当前游戏页面必须是继承自BaseActivity.class
            Activity act = appInterface.getAct();
            if (act != null) act.finish();
        }

        // 吐司提示
        public void show_toast(String data) {
            JSONObject dataObject = JsonUtil.getJsonObject(data);
            PToast.showShort(dataObject.optString("content"));
        }

        // 复制内容到剪切板
        public void do_copy_to_bord(String data) {
            JSONObject dataObject = JsonUtil.getJsonObject(data);
            String content = dataObject.optString("content");

            if (Build.VERSION.SDK_INT > 11) {
                // 得到剪贴板管理器
                android.content.ClipboardManager clipboard = (android.content.ClipboardManager) appInterface.getAct().getSystemService(Context.CLIPBOARD_SERVICE);
                clipboard.setPrimaryClip(ClipData.newPlainText("Label", content));
            } else {
                android.text.ClipboardManager cmb = (android.text.ClipboardManager) appInterface.getAct().getSystemService(Context.CLIPBOARD_SERVICE);
                cmb.setText(content);
            }
            PickerDialogUtil.showSimpleTipDialogExt((FragmentActivity) App.getActivity(), new SimpleTipDialog.ConfirmListener() {
                @Override
                public void onCancel() {
                }

                @Override
                public void onSubmit() {
                    APKUtil.openAlipayClient();
                }
            }, "恭喜您，打开支付宝即可成功领取！", "领取成功", "稍后打开", "立即打开", true, R.color.text_gray);
        }

        // 邀请好友
        public void do_invite_friend(String data) {
            ShareUtils.getInstance().reqShareData(new RequestComplete() {
                @Override
                public void onRequestComplete(HttpResponse response) {
                    if (!response.isOk()) {
                        PToast.showShort("获取分享数据失败，请稍后重试");
                        return;
                    }
                    PickerDialogUtil.showShareRedDialog((FragmentActivity) appInterface.getAct());
                }
            });
        }

        // 打开充值弹框
        public void do_pay(String data) {
            PickerDialogUtil.showPayDialog((FragmentActivity) App.getActivity());
        }

        // 打印JS log日志
        public void do_log(String data) {
            JSONObject dataObject = JsonUtil.getJsonObject(data);
            final String log = dataObject.optString("log");
            MsgMgr.getInstance().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.d("jslogger", log);
                }
            });
        }

        // JS加载完成通知
        public void do_js_finish(String data) {
            JSReturnUid();
        }
    }

    // ==================================== JS cmd处理 ===================================
    public static final String JSCMD_refresh_web = "refresh_web";   //主动调用刷新web页面
    public static final String JSCMD_return_uid = "return_uid";     //传递uid给web

    /**
     * JSCMD：给JS传递用户uid
     */
    public void JSReturnUid() {
        Map<String, Object> data = new HashMap<>();
        data.put("uid", ModuleMgr.getCenterMgr().getMyInfo().getUid());
        data.put("auth", ModuleMgr.getLoginMgr().getAuth());
        doInJS(Invoker.JSCMD_return_uid, data);
    }
}
